package com.zhijian.medical.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.google.common.collect.Lists;
import com.zhijian.medical.dao.local.EmailSendMapper;
import com.zhijian.medical.entity.po.EmailSend;
import com.zhijian.medical.entity.po.Message;
import com.zhijian.medical.entity.vo.request.EmailSendSaveOrUpdateVo;
import com.zhijian.medical.entity.vo.request.EmailSendSearchVo;
import com.zhijian.medical.entity.vo.request.PersonSearchVo;
import com.zhijian.medical.entity.vo.response.EmailSendVo;
import com.zhijian.medical.entity.vo.response.PersonVo;
import com.zhijian.medical.enums.EmailSendStatusEnum;
import com.zhijian.medical.enums.MessageEnum;
import com.zhijian.medical.enums.PersonTypeEnum;
import com.zhijian.medical.service.EmailSendService;
import com.zhijian.medical.service.MessageService;
import com.zhijian.medical.service.PersonService;
import com.zhijian.medical.util.AssertUtil;
import com.zhijian.medical.util.Page;
import com.zhijian.medical.util.SendEmailUtil;
import com.zhijian.medical.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 发送邮件业务处理层
 *
 * @author auto
 * @version: 1.0
 * @date 2023-12-27 20:31:03
 */
@Slf4j
@Service
public class EmailSendServiceImpl implements EmailSendService {

    @Autowired
    private EmailSendMapper mapper;

    @Autowired
    private MessageService messageService;

    @Autowired
    private PersonService personService;

    @Override
    public EmailSend selectById(Long id) {
        return mapper.selectByPrimaryKey(id);
    }

    @Override
    public EmailSendVo selectVoById(Long id) {
        return mapper.selectVoById(id);
    }

    @Override
    public void deleteById(Long id) {
        mapper.deleteByPrimaryKey(id);
    }

    @Override
    public void deleteByIdList(List<Long> idList) {
        if (CollectionUtil.isEmpty(idList)) {
            return;
        }
        mapper.deleteByIdList(idList);
    }

    @Override
    public Long insert(EmailSend emailSend) {
        Date now = new Date();
        emailSend.setCreateTime(now);
        emailSend.setUpdateTime(now);
        return mapper.insert(emailSend) > 0 ? emailSend.getId() : 0L;
    }

    @Override
    public boolean update(EmailSend emailSend) {
        Date now = new Date();
        emailSend.setUpdateTime(now);
        return mapper.updateByPrimaryKey(emailSend) != 0;
    }

    @Override
    public boolean updateByPrimaryKeySelective(EmailSend record) {
        Date now = new Date();
        record.setUpdateTime(now);
        return mapper.updateByPrimaryKeySelective(record) != 0;
    }

    @Override
    public boolean save(EmailSendSaveOrUpdateVo saveOrUpdateVo) {
        EmailSend emailSend = new EmailSend();
        BeanUtils.copyProperties(saveOrUpdateVo, emailSend);
        //接收人员类型
        List<Long> userTypeList = saveOrUpdateVo.getUserTypeList();
        emailSend.setUserTypes(StrUtil.join(",", userTypeList));
        //默认未发送
        emailSend.setStatus(EmailSendStatusEnum.UN_SEND.getCode().byteValue());
        return this.insert(emailSend) != 0;
    }

    @Override
    public boolean modify(EmailSendSaveOrUpdateVo saveOrUpdateVo) {
        EmailSend old = this.selectById(saveOrUpdateVo.getId());
        AssertUtil.notNull(old, "此数据不存在或者已被删除");
        AssertUtil.check(Objects.nonNull(old.getStatus()) && old.getStatus() == EmailSendStatusEnum.ALREADY_SEND.getCode().byteValue(), "已经发送的数据禁止修改");
        EmailSend emailSend = new EmailSend();
        BeanUtils.copyProperties(saveOrUpdateVo, emailSend);
        //接收人员类型
        List<Long> userTypeList = saveOrUpdateVo.getUserTypeList();
        emailSend.setUserTypes(StrUtil.join(",", userTypeList));
        return this.update(emailSend);
    }

    @Override
    public Integer count(EmailSendSearchVo emailSendSearchVo) {
        return mapper.count(emailSendSearchVo);
    }

    @Override
    public List<EmailSendVo> selectList(EmailSendSearchVo emailSendSearchVo) {
        List<EmailSendVo> emailSendVos = mapper.selectList(emailSendSearchVo);
        if (CollectionUtil.isNotEmpty(emailSendVos)) {

            for (EmailSendVo emailSendVo : emailSendVos) {
                String userTypes = emailSendVo.getUserTypes();
                List<String> personTypeNames = Lists.newLinkedList();
                List<Long> userTypeList = Lists.newLinkedList();
                Arrays.stream(userTypes.split(",")).forEach(s -> {
                    PersonTypeEnum personTypeEnum = PersonTypeEnum.getByCode(Integer.valueOf(s));
                    if (Objects.nonNull(personTypeEnum)) {
                        personTypeNames.add(personTypeEnum.getMsg());
                    }
                    userTypeList.add(Long.valueOf(s));
                });
                emailSendVo.setUserTypeNames(String.join(",", personTypeNames.stream().filter(StringUtils::isNotBlank).collect(Collectors.toList())));
                emailSendVo.setUserTypeList(userTypeList);
            }
        }
        return emailSendVos;
    }

    @Override
    public Page<EmailSendVo> selectPage(EmailSendSearchVo emailSendSearchVo) {
        //先直接查总数
        int count = count(emailSendSearchVo);
        //分页
        Page<EmailSendVo> page = new Page<>(true, count, emailSendSearchVo.getPageNum(), emailSendSearchVo.getPageSize());
        emailSendSearchVo.setStartIndex(page.getStartIndex());
        page.setPage(true);
        page.setTotalCount(count);
        List<EmailSendVo> responseVos = this.selectList(emailSendSearchVo);
        page.setData(responseVos);
        return page;
    }

    @Override
    public boolean insertBatch(List<EmailSend> entities) {
        return CollectionUtil.isNotEmpty(entities) && mapper.insertBatch(entities) > 0;
    }

    @Override
    public boolean send(Long id) {
        EmailSend old = this.selectById(id);
        AssertUtil.notNull(old, "此数据不存在或者已被删除");
        AssertUtil.check(old.getStatus() == EmailSendStatusEnum.ALREADY_SEND.getCode().byteValue(), "已经发送的数据禁止再次发送");
        Date now = new Date();
        this.updateByPrimaryKeySelective(EmailSend.builder()
                .id(id)
                .status(EmailSendStatusEnum.ALREADY_SEND.getCode().byteValue())
                .sendTime(now)
                .build());
        String userTypes = old.getUserTypes();
        //查出所有人
        List<PersonVo> personVos = personService.selectList(PersonSearchVo.builder()
                .typeList(Arrays.stream(userTypes.split(",")).map(Byte::valueOf).collect(Collectors.toList()))
                .build());
        if (CollectionUtil.isNotEmpty(personVos)) {
            List<Message> messages = Lists.newLinkedList();

            for (PersonVo personVo : personVos) {
                String email = personVo.getEmail();
                if (StringUtils.isNotBlank(email)) {
                    Message m = new Message();
                    m.setTitle("邮件发送：" + old.getTitle());
                    //告警内容
                    m.setContent(old.getContent());
                    m.setSendTime(now);
                    m.setReceiveType(MessageEnum.MessageReceiveTypeEnum.PC.getCode().byteValue());
                    m.setReceiveUserId(personVo.getId());
                    m.setType(MessageEnum.MessageTypeEnum.EMAIL.getCode().byteValue());
                    m.setDataId(old.getId());
                    //未读
                    m.setWeatherRead(MessageEnum.MessageWeatherReadEnum.UN_READ.getCode().byteValue());

                    m.setCreateTime(now);
                    m.setUpdateTime(now);
                    try {
                        SendEmailUtil.sendEmail(email, old.getTitle(), old.getContent());
                        m.setResult("ok");
                    } catch (Exception e) {
                        e.printStackTrace();
                        m.setResult("fail");
                    }
                    messages.add(m);
                }
            }
            if (CollectionUtil.isNotEmpty(messages)) {
                messageService.insertBatch(messages);
            }
        }
        return true;
    }

    @Override
    public List<EmailSend> selectFixList() {
        return mapper.selectFixList();
    }

}